package com.small.site.service.impl;

import com.small.site.base.IRolePermissionService;
import com.small.site.base.IRoleService;
import com.small.site.enums.ResponseCode;
import com.small.site.exception.BusinessException;
import com.small.site.pojo.SysRole;
import com.small.site.pojo.SysRolePermission;
import com.small.site.service.RoleService;
import com.small.site.util.Builder;
import com.small.site.util.IdWorker;
import com.small.site.util.R;
import com.small.site.vo.PageVo;
import com.small.site.vo.req.RolePageReqVo;
import com.small.site.vo.req.RoleReqVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author xiaochi
 * @date 2021/12/16 15:01
 * @desc RoleServiceImpl
 */
@Slf4j
@Service
@SuppressWarnings("all")
public class RoleServiceImpl implements RoleService {

    @DubboReference(check = false)
    private IRoleService roleService;
    @DubboReference(check = false)
    private IRolePermissionService rolePermissionService;
    @Autowired
    private IdWorker idWorker;

    /**
     * 分页获取角色
     * @param rolePageReqVo
     * @return
     */
    @Override
    public PageVo<SysRole> findPage(RolePageReqVo rolePageReqVo) {
        return roleService.findPage(rolePageReqVo.getPageNum(),rolePageReqVo.getPageSize(),SysRole.builder().deleted(1).build());
    }

    /**
     * 新增角色
     * @param roleReqVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<String> createRole(RoleReqVo roleReqVo) {
        if (null == roleReqVo.getPermissionsIds() || roleReqVo.getPermissionsIds().isEmpty()){
            throw new BusinessException(ResponseCode.DATA_ERROR);
        }
        String roleId = String.valueOf(idWorker.nextId());
        SysRole sysRole = roleReqVo.buildEntity();
        sysRole.setId(roleId);
        int result = roleService.insert(sysRole);
        if (result == 0){
            throw new BusinessException(ResponseCode.ERROR);
        }
        // 添加 角色 权限关联表 数据(添加之前，先删除原来角色 id 对应的所有权限id)
        // 添加之前，先删除原来角色 id 对应的所有权限id
        rolePermissionService.deleteByWhere(SysRolePermission.builder().roleId(roleId).build());
        // 权限id集合为空，表示删除该角色对应的所有权限
        if (ObjectUtils.isEmpty(roleReqVo.getPermissionsIds())){
            return R.ok();
        }
        if (result == insertRolePermission(roleReqVo.getPermissionsIds(),roleId)){
            throw new BusinessException(ResponseCode.ERROR);
        }
        return R.ok();
    }

    /**
     * 获取角色详情接口
     * @param roleId
     * @return
     */
    @Override
    public Set<String> getRoleById(String roleId) {
        if (StringUtils.isBlank(roleId)){
            throw new BusinessException(ResponseCode.DATA_ERROR);
        }
        // 通过角色id查询拥有的权限ids
        return rolePermissionService.findByWhere(SysRolePermission.builder().roleId(roleId).build()).stream().map(x -> x.getPermissionId()).collect(Collectors.toSet());
    }

    /**
     * 更新角色
     * @param roleUpdateReqVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<String> updateRole(RoleReqVo roleReqVo) {
        SysRole sysRole = roleService.findOne(roleReqVo.getId());
        if (sysRole == null){
            throw new BusinessException(ResponseCode.DATA_ERROR);
        }
        int result = roleService.updateById(roleReqVo.buildEntity());
        if (result != 1){
            throw new BusinessException(ResponseCode.ERROR);
        }
        // 更新 角色 权限 关联表(更新之前，先删除原来角色 id 对应的所有权限id)
        rolePermissionService.deleteByWhere(SysRolePermission.builder().roleId(roleReqVo.getId()).build());
        insertRolePermission(roleReqVo.getPermissionsIds(),roleReqVo.getId());
        return R.ok();
    }

    /**
     * 更新角色状态
     * @param roleId
     * @param status
     * @return
     */
    @Override
    public R<String> updateRoleStatus(String roleId, Integer status) {
        if (StringUtils.isBlank(roleId)|| ObjectUtils.isEmpty(status)){
            return R.error(ResponseCode.DATA_ERROR.getMessage());
        }
        int result = roleService.updateById(SysRole.builder().id(roleId).status(status).updateTime(new Date()).build());
        if (result == 0){
            return R.error();
        }
        return R.ok();
    }

    /**
     * 删除角色
     * @param roleId
     * @return
     */
    @Override
    public R<String> deletedRole(String roleId) {
        int result = roleService.updateById(SysRole.builder().id(roleId).deleted(0).updateTime(new Date()).build());
        if (result != 1){
            throw new BusinessException(ResponseCode.ERROR);
        }
        //角色菜单权限关联数据删除，通过角色id删除权限id
        rolePermissionService.deleteByWhere(SysRolePermission.builder().roleId(roleId).build());
        return R.ok();
    }

    /**
     * 角色权限数据入库
     * @return
     */
    private int insertRolePermission(List<String> permissionsIds,String roleId){
        Date date = new Date();
        return rolePermissionService.insertBatch(permissionsIds.stream().map(permissionId ->
                Builder.of(SysRolePermission::new)
                        .with(SysRolePermission::setId,String.valueOf(idWorker.nextId()))
                        .with(SysRolePermission::setRoleId,roleId)
                        .with(SysRolePermission::setPermissionId,permissionId)
                        .with(SysRolePermission::setCreateTime,date)
                        .build()
        ).collect(Collectors.toList()));
    }
}
